﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using GRIP;
using TUIO;
using System.Windows.Forms;

namespace WindowsControl
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Timer timer;
        KinectAdapter kinect;
        private TuioContact[][] kinect_points;
        private Brush blueBrush = new SolidColorBrush(Color.FromRgb(0, 0, 255));
        private Brush greenBrush = new SolidColorBrush(Color.FromRgb(0, 255, 0));
        private Brush redBrush = new SolidColorBrush(Color.FromRgb(255, 0, 0));
        private Brush yellowBrush = new SolidColorBrush(Color.FromRgb(255, 255, 0));
        private List<TuioContact> fingersLeft;
        private List<TuioContact> fingersRight;
        private Brush[] fingerBrushes = { new SolidColorBrush(Color.FromRgb(0, 255, 0)),
                                          new SolidColorBrush(Color.FromRgb(155, 255, 0)),
                                          new SolidColorBrush(Color.FromRgb(255, 255, 0)),
                                          new SolidColorBrush(Color.FromRgb(255, 255, 155)),
                                          new SolidColorBrush(Color.FromRgb(255, 255, 255))
                                        };
        private int WindowWidth;
        private int WindowHeight;

        public MainWindow()
        {
            InitializeComponent();
            ControlForm control = new ControlForm();
            control.Show();
            System.Drawing.Rectangle screen = Screen.AllScreens[0].Bounds;
            this.Topmost = true;
            
            this.Left = screen.X;
            this.Top = screen.Y;
            this.Width = WindowWidth = screen.Width;
            this.Height = WindowHeight = screen.Height;

            Canvas.SetLeft(MainCanvas, screen.X);
            Canvas.SetTop(MainCanvas, screen.Y);

            ConfigParser parser = new ConfigParser("config.xml");
            KinectSettings kinectSettings = new KinectSettings();
            FingerSettings fingerSettings = new FingerSettings();
            try
            {
                parser.LoadConfiguration(kinectSettings);
                parser.LoadConfiguration(fingerSettings);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            kinect = new KinectAdapter(kinectSettings, fingerSettings);

            kinect_points = new TuioContact[][]
            {
                 new TuioContact[] { kinect.Head, kinect.ShoulderCenter, kinect.Spine, kinect.HipCenter },
                 new TuioContact[] { kinect.ShoulderCenter, kinect.ShoulderLeft, kinect.ElbowLeft, kinect.WristLeft, kinect.HandLeft },
                 new TuioContact[] { kinect.ShoulderCenter, kinect.ShoulderRight, kinect.ElbowRight, kinect.WristRight, kinect.HandRight },
                 new TuioContact[] { kinect.HipCenter, kinect.HipLeft, kinect.KneeLeft, kinect.AnkleLeft, kinect.FootLeft },
                 new TuioContact[] { kinect.HipCenter, kinect.HipRight, kinect.KneeRight, kinect.AnkleRight, kinect.FootRight }
            };

            fingersLeft = new List<TuioContact>(new TuioContact[] { kinect.ThumbLeft, kinect.IndexFingerLeft, kinect.MiddleFingerLeft, kinect.RingFingerLeft, kinect.PinkyLeft });
            fingersRight = new List<TuioContact>(new TuioContact[] { kinect.ThumbRight, kinect.IndexFingerRight, kinect.MiddleFingerRight, kinect.RingFingerRight, kinect.PinkyRight });


            timer = new Timer();
            timer.Interval = 40;
            timer.Tick += new EventHandler(timer_Elapsed);
            timer.Start();
        }

        void timer_Elapsed(object sender, EventArgs e)
        {
            drawSkeleton();
        }

        public void drawSkeleton()
        {
            MainCanvas.Children.Clear();
            TuioContact[] contacts;
            TuioContact contact;
            PointCollection points;
            List<TuioContact> activeContacts = kinect.getContacts();

            for (int i = 0; i < kinect_points.Length; i++)
            {
                points = new PointCollection();
                contacts = kinect_points[i];
                for (int j = 0; j < contacts.Length; j++)
                {
                    contact = contacts[j];
                    if (contact.active)
                        points.Add(new Point(contact.xpos * WindowWidth, contact.ypos * WindowHeight));
                }
                drawLine(points);
            }

            for (int i = 0; i < activeContacts.Count; i++)
            {
                contact = activeContacts[i];
                if (contact.active)
                    drawPoint(contact, blueBrush);
            }

            drawHand(fingersLeft, kinect.HandLeft);
            drawHand(fingersRight, kinect.HandRight);
        }

        private void drawPoint(TuioContact contact, Brush brush)
        {
            Ellipse ellipse = new Ellipse();
            ellipse.Width = 12;
            ellipse.Height = 12;
            Canvas.SetLeft(ellipse, contact.xpos * WindowWidth - 6);
            Canvas.SetTop(ellipse, contact.ypos * WindowHeight - 6);
            ellipse.Stroke = brush;
            ellipse.StrokeThickness = 12;
            MainCanvas.Children.Add(ellipse);
        }

        private void drawLine(PointCollection points)
        {
            Polyline polyline = new Polyline();
            polyline.Points = points;
            polyline.Stroke = redBrush;
            polyline.StrokeThickness = 5;
            MainCanvas.Children.Add(polyline);
        }

        private void drawHand(List<TuioContact> fingerPoints, TuioContact hand)
        {
            for (int i = 0; i < fingerPoints.Count; i++)
            {
                TuioContact finger = fingerPoints[i];
                if (finger.active)
                {
                    PointCollection points = new PointCollection();
                    points.Add(new Point(hand.xpos * WindowWidth, hand.ypos * WindowHeight));
                    points.Add(new Point(finger.xpos * WindowWidth, finger.ypos * WindowHeight));

                    drawLine(points);
                    drawPoint(finger, greenBrush);
                }
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            kinect.shutdown();
            Environment.Exit(0);
        }
    }
}
